﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Windows.Forms;

namespace MakeBorderless
{
    public partial class frmMain : Form
    {
        #region Variables

        List<Process> _processes;
        List<ProcessGroup> _groups;

        Settings _settings;
        Settings _newSettings;
        bool _ranFromConsole = false;
        bool _updatingCheckState = false;

        #endregion Variables

        #region Public Members

        #region Constructor

        public frmMain(Settings s, bool console)
        {
            if (s != null)
            {
                _ranFromConsole = console;
                _settings = (Settings)s.Copy();
            }
            InitializeComponent();
        }

        #endregion Constructor

        #endregion Public Members

        #region Private Members

        #region Methods

        private void RefreshWindows()
        {
            trvWindows.Nodes.Clear();
            _processes = Styler.GetVisibleWindowsAsProcess();
            List<ProcessGroup> groups = new List<ProcessGroup>();

            foreach (Process p in _processes)
            {
                if (_newSettings.GroupEnabled)
                {
                    string name = "";
                    if (_newSettings.GroupBy == GroupType.UseWindowName)
                    {
                        name = p.MainWindowTitle;
                    }
                    else
                    {
                        name = p.ProcessName;
                    }
                    ProcessGroup tempg = new ProcessGroup(name, chkGroupWindow.Checked);
                    tempg.Add(p);
                    bool isNew = true;
                    foreach (ProcessGroup pg in groups)
                    {
                        if (pg.Name.ToLower() == tempg.Name.ToLower())
                        {
                            pg.Add(p);
                            isNew = false;
                            break;
                        }
                    }
                    if (isNew)
                    {
                        groups.Add(tempg);
                    }
                }
                else
                {
                    TreeNode tn = new TreeNode(p.MainWindowTitle);
                    tn.Checked = Styler.IsStyled(p);
                    trvWindows.Nodes.Add(tn);
                }
            }
            if (_newSettings.GroupEnabled)
            {
                _groups = groups;
                BuildTreeView();
            }
        }

        private void BuildTreeView()
        {
            if (_newSettings.GroupEnabled)
            {
                trvWindows.Nodes.Clear();
                trvWindows.Name = String.Format("Windows (Sorted by {0})",
                    (chkGroupWindow.Checked ? "Window Name" : "Process Name"));
                trvWindows.CheckBoxes = true;
                foreach (ProcessGroup pg in _groups)
                {
                    string nodeStr = "";
                    if (pg.Count > 1)
                    {
                        nodeStr = String.Format("{0} ({1})", pg.Name, pg.Count);
                        TreeNode groupnode = new TreeNode(nodeStr);
                        foreach (GroupItem i in pg.GroupItems)
                        {
                            TreeNode windownode = new TreeNode(i.Name);
                            windownode.Checked = i.IsStyled;
                            groupnode.Nodes.Add(windownode);
                        }
                        groupnode.Checked = pg.AllStyled;
                        trvWindows.Nodes.Add(groupnode);
                    }
                    else
                    {
                        nodeStr = pg.Name;
                        TreeNode windownode = new TreeNode(nodeStr);
                        windownode.Checked = pg.AllStyled;
                        trvWindows.Nodes.Add(windownode);
                    }
                }
            }
        }

        private int GetGroupIndex(string name)
        {
            for (int i = 0; i < _groups.Count; i++)
            {
                if (_groups[i].Name.ToLower() == name.ToLower())
                {
                    return i;
                }
            }
            return -1;
        }

        private void SaveSettings()
        {
            SettingsManager mgr = new SettingsManager(Path.Combine(Application.StartupPath, "settings"), "settings.xml", _newSettings);
            mgr.Save();
            _settings = (Settings)_newSettings.Copy();
        }

        private void LoadSettings()
        {
            Settings s = new Settings();
            SettingsManager mgr = new SettingsManager(Path.Combine(Application.StartupPath, "settings"), "settings.xml", s);
            s = (Settings)mgr.Load();

            if (s != null)
            {
                _settings = (Settings)s.Copy();
                _newSettings = (Settings)s.Copy();
                ParseSavedNames(s.SavedNames);
            }
        }

        private void ApplySettings()
        {
            chkGroupWindow.Checked = (_settings.GroupBy == GroupType.UseWindowName);
            chkGroupProcess.Checked = (_settings.GroupBy == GroupType.UseProcessName);
            if (_settings.RunMinimized)
            {
                this.WindowState = FormWindowState.Minimized;
            }
        }

        private void ParseSavedNames(List<string> names)
        {
            foreach (String n in names)
            {
                Styler.SetAllBorderless(n, (_newSettings.GroupBy == GroupType.UseWindowName));
            }
        }

        private List<string> GetStyledNames()
        {
            List<string> names = new List<string>();
            foreach (Process p in _processes)
            {
                if (Styler.IsStyled(p))
                {
                    string name = "";
                    if (_newSettings.GroupEnabled)
                    {
                        name = (_newSettings.GroupBy == GroupType.UseWindowName ? p.MainWindowTitle : p.ProcessName);
                    }
                    else
                    {
                        name = p.MainWindowTitle;
                    }
                    if (!names.Contains(name))
                    {
                        names.Add(name);
                    }
                }
            }
            return names;
        }

        private void RefreshSettings()
        {
            _newSettings = new Settings(GetGroupType(), chkRunMinimized.Checked, GetStyledNames());
            chkSave.Checked = !(_settings != _newSettings);
            chkSave.Text = (chkSave.Checked ? "Settings Saved" : "Save Settings");
        }

        private GroupType GetGroupType()
        {
            if (chkGroupWindow.Checked)
            {
                return GroupType.UseWindowName;
            }
            else if (chkGroupProcess.Checked)
            {
                return GroupType.UseProcessName;
            }
            return GroupType.None;
        }

        #endregion Methods

        #region Event Handlers

        #region Form Controls

        private void frmMain_Load(object sender, EventArgs e)
        {
            if (_ranFromConsole)
            {
                ParseSavedNames(_settings.SavedNames);
            }
            else
            {
                LoadSettings();
            }
            ApplySettings();
            RefreshWindows();
        }

        private void btnRefresh_Click(object sender, EventArgs e)
        {
            RefreshWindows();
        }

        private void CheckChildNodes(TreeNode node, bool checkState)
        {
            foreach (TreeNode n in node.Nodes)
            {
                n.Checked = checkState;
            }
        }

        private void trvWindows_AfterCheck(object sender, TreeViewEventArgs e)
        {
            if (_updatingCheckState)
            {
                _updatingCheckState = false;
                return;
            }

            if (e.Node.Nodes.Count > 0)
            {
                CheckChildNodes(e.Node, e.Node.Checked);
                if (_newSettings.GroupEnabled)
                {
                    if (e.Node.Checked)
                    {
                        Styler.SetAllBorderless(e.Node.Nodes[0].Text, (_newSettings.GroupBy == GroupType.UseWindowName));
                    }
                    else
                    {
                        Styler.ResetAllBorders(e.Node.Nodes[0].Text, (_newSettings.GroupBy == GroupType.UseWindowName));
                    }
                }
            }
            else
            {
                if (_newSettings.GroupEnabled)
                {
                    int gInd = GetGroupIndex(e.Node.Text);
                    int nInd = 0;
                    if (_groups[gInd].Processes.Count > 1)
                    {
                        nInd = e.Node.Index;
                    }
                    Process p = _groups[gInd].Processes[nInd];
                    if (e.Node.Checked)
                    {
                        Styler.SetBorderless(p);
                    }
                    else
                    {
                        Styler.ResetBorder(p);
                    }

                    if (e.Node.Parent != null)
                    {
                        _updatingCheckState = true;
                        e.Node.Parent.Checked = _groups[gInd].AllStyled;
                    }
                }
                else
                {
                    Process p = _processes[e.Node.Index];
                    if (e.Node.Checked)
                    {
                        Styler.SetBorderless(p);
                    }
                    else
                    {
                        Styler.ResetBorder(p);
                    }
                }
            }
            RefreshSettings();
        }

        private void chkGroupWindow_Click(object sender, EventArgs e)
        {
            if (chkGroupProcess.Checked)
            {
                chkGroupProcess.Checked = false;
                chkGroupWindow.Checked = true;
            }
            RefreshSettings();
            RefreshWindows();
        }

        private void chkGroupProcess_Click(object sender, EventArgs e)
        {
            if (chkGroupWindow.Checked)
            {
                chkGroupWindow.Checked = false;
                chkGroupProcess.Checked = true;
            }
            RefreshSettings();
            RefreshWindows();
        }

        private void chkSave_Click(object sender, EventArgs e)
        {
            SaveSettings();
            RefreshSettings();
        }

        private void chkRunMinimized_Click(object sender, EventArgs e)
        {
            RefreshSettings();
        }

        #endregion Form Controls

        private void frmMain_Shown(object sender, EventArgs e)
        {
            RefreshWindows();
        }

        #endregion Event Handlers

        #endregion Private Members
    }
}